﻿using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using CommunityToolkit.Mvvm.Messaging;
using DependencyInjectionHelperLib.Attributes;
using DependencyInjectionHelperLib.Eunms;
using DependencyInjectionHelperLib.Navigation;
using LiveChartsCore;
using LiveChartsCore.Defaults;
using LiveChartsCore.SkiaSharpView;
using LiveChartsCore.SkiaSharpView.Painting;
using MeterReader.Common.Extensions;
using MeterReader.Messages;
using MeterReader.Models;
using SkiaSharp;
using System.Collections.ObjectModel;

namespace MeterReader.ViewModels
{
    [DIRegistration(lifetime: Lifetimes.Transient, pageKey: "History")]
    public partial class HistoryViewModel : ObservableObject
    {
        private INavigationObjectProvider? _navigationObjectProvider;
        private MeterDBContext? _meterDBContext;
        private ObservableCollection<DateTimePoint>? _dateTimePoints = new();

        public HistoryViewModel()
        { }

        public HistoryViewModel(INavigationObjectProvider navigationObjectProvider, MeterDBContext meterDBContext)
        {
            _navigationObjectProvider = navigationObjectProvider;
            _meterDBContext = meterDBContext;
            LiveCharts.Configure(config => config.HasGlobalSKTypeface(SKFontManager.Default.MatchCharacter('汉')));
            Series[0].Values = _dateTimePoints;
            ComBoxSource = _meterDBContext!.GetMeterColumnsFromTMeters().ToList();
        }

        public Axis[] XAxes { get; set; } =
            {
                new DateTimeAxis(TimeSpan.FromHours(1), date => date.ToString("yyyy-MM-dd HH:mm:ss"))
                {
                    NameTextSize = 15,
                    LabelsRotation = 15,
                    NamePaint = new SolidColorPaint(SKColors.WhiteSmoke),
                    LabelsPaint = new SolidColorPaint(SKColors.DarkGray),
                    TextSize = 15,
                    SeparatorsPaint = new SolidColorPaint(SKColors.LightSlateGray) { StrokeThickness = 2 },
                }
            };

        public Axis[] YAxes { get; set; } =
            [
                new Axis()
                {
                    Name = "总功率(Kw.h)",
                    NameTextSize = 15,
                    NamePaint = new SolidColorPaint(SKColors.WhiteSmoke),
                    LabelsPaint = new SolidColorPaint(SKColors.DarkGray),
                    TextSize = 15,
                    MinLimit = 0,
                    SeparatorsPaint = new SolidColorPaint(SKColors.LightSlateGray) { StrokeThickness = 2 },
                    Labeler = v => $"{v}(Kw.h)"
                }
            ];

        public ObservableCollection<ISeries> Series { get; set; } =
            new()
            {
                new LineSeries<DateTimePoint>()
                {
                    Fill = null,
                    GeometrySize = 0,
                    LineSmoothness = 1,
                }
            };

        [ObservableProperty]
        [NotifyCanExecuteChangedFor(nameof(SearchHistoryCommand))]
        private DateTime? _beginDateTime = DateTime.Now;

        [ObservableProperty]
        [NotifyCanExecuteChangedFor(nameof(SearchHistoryCommand))]
        private DateTime? _endDateTime = DateTime.Now;

        [ObservableProperty]
        private List<string> _comBoxSource = new();

        [ObservableProperty]
        private string _comBoxSelectedItem = "Col1";

        [RelayCommand]
        private void GoBackDataMonitorView(string key)
        {
            var vm = _navigationObjectProvider!.GetNavigationObject<MetersDataMonitorViewModel>(key);
            _ = WeakReferenceMessenger.Default.Send(new NavigateRequestMessage(vm!));
        }

        [RelayCommand(CanExecute = (nameof(CanSearchHistory)))]
        private void SearchHistory()
        {
            var query = _meterDBContext!.TMeters!.Where(t => t.Date >= BeginDateTime && t.Date <= EndDateTime);
            if (query.Any())
            {
                var dateTimePoints = query.Select(t => new DateTimePoint(t.Date!, t.GetProperty(ComBoxSelectedItem)));

                if (dateTimePoints.Any())
                {
                    _dateTimePoints!.Clear();
                    foreach (var item in dateTimePoints)
                    {
                        _dateTimePoints!.Add(item);
                    }
                }
            }
        }

        private bool CanSearchHistory() => EndDateTime > BeginDateTime;
    }
}